home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS09.ADF
/
MicroEMACS
/
mouse.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-05-22
|
13KB
|
505 lines
/*
* This file implements memacs support for the Amiga mouse.
* Author: Andy Poggio
*/
#include <exec/types.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <devices/console.h>
#include <stdio.h>
#include "ed.h"
#define NL 0
extern struct Window *Window;
/* Font sizes */
#define FONT_X 8
#define FONT_Y 8
/* Button Codes */
#define LEFT_BUTTON 1
#define RIGHT_BUTTON 2
/* Copies of this structure will get "stamped" into many more */
/* Allocated later */
struct IntuiText generic = {
0, 1, /* Bluepen, Whitepen */
JAM2, 5, /* mode, LeftEdge */
0, NL, /* Top (to be filled later), Font */
NL, /* Name (to be filled later) */
NL /* Next one */
};
#define NUM_MENUS 4
/* Menu numbers */
#define PRO_MENU 0
#define REG_MENU 1
#define COM_MENU 2
#define OPT_MENU 3
/* Menu Widths */
#define COM_WIDTH 72
#define ITEM_WIDTH 112
/* All items in these menus have the following flags set */
#define BLACK_FILL ITEMTEXT | ITEMENABLED | HIGHCOMP
/** FILE MENU ITEMS **/
#define NUM_PRO_ITEMS 6
#define NUM_REG_ITEMS 4
#define NUM_COM_ITEMS 7
#define NUM_OPT_ITEMS 6
#define NEWBUF_ITEM 0
#define OPEN_ITEM 1
#define SAVE_ITEM 2
#define SAVEAS_ITEM 3
#define QUITNSAVE_ITEM 4
#define QUIT_ITEM 5
#define KILL_ITEM 0
#define COPY_ITEM 1
#define UNKILL_ITEM 2
#define FILEYANK_ITEM 3
#define NOOP_ITEM 0
#define SEARCH_ITEM 1
#define QUERY_ITEM 2
#define STARTM_ITEM 3
#define ENDM_ITEM 4
#define EXECM_ITEM 5
#define NEW_ITEM 6
#define TWO_ITEM 0
#define ONE_ITEM 1
#define AUTOIND_ITEM 2
#define WORDRAP_ITEM 3
#define LEFTMAR_ITEM 4
#define RIGHTMAR_ITEM 5
struct MenuItem pro_items[NUM_PRO_ITEMS];
struct IntuiText pro_names[NUM_PRO_ITEMS];
struct MenuItem reg_items[NUM_REG_ITEMS];
struct IntuiText reg_names[NUM_REG_ITEMS];
struct MenuItem com_items[NUM_COM_ITEMS];
struct IntuiText com_names[NUM_COM_ITEMS];
struct MenuItem opt_items[NUM_OPT_ITEMS];
struct IntuiText opt_names[NUM_OPT_ITEMS];
char *promenu_names[] = {
"New Buffer ",
"Open ",
"Save ",
"Save As ",
"Quit & Save",
"Quit "
};
char *regmenu_names[] = {
"Cut ",
"Copy ",
"Paste ",
"File Paste "
};
char *commenu_names[] = {
"No Operaton ",
"Search ",
"Replace ",
"Start Macro ",
"End Macro ",
"Execute Macro",
"New CLI "
};
char *optmenu_names[] = {
"Split Window",
"One Window ",
"Auto indent ",
"Word wrap ",
"Left Margin ",
"Right Margin"
};
struct Menu pmenu = {
NULL, /* Pointer to next menu */
0, 0, COM_WIDTH, 10, /* LeftEdge, TopEdge, Width, Height */
MENUENABLED, /* FLAGS */
"Project", /* Menu name */
pro_items /* First item structure */
};
struct Menu rmenu = {
NULL, /* Pointer to next menu */
COM_WIDTH, 0, COM_WIDTH, 10, /* LeftEdge, TopEdge, Width, Height */
MENUENABLED, /* FLAGS */
"Region", /* Menu name */
reg_items /* First item structure */
};
struct Menu cmenu = {
NULL, /* Pointer to next menu */
COM_WIDTH*2, 0, COM_WIDTH, 10, /* LeftEdge, TopEdge, Width, Height */
MENUENABLED, /* FLAGS */
"Commands", /* Menu name */
com_items /* First item structure */
};
struct Menu omenu = {
NULL, /* Pointer to next menu */
COM_WIDTH*3, 0, COM_WIDTH, 10, /* LeftEdge, TopEdge, Width, Height */
MENUENABLED, /* FLAGS */
" Options", /* Menu name */
opt_items /* First item structure */
};
mouse_setup_menu()
{
mouse_newmenu( &pmenu, promenu_names, pro_items, pro_names,
NUM_PRO_ITEMS, ITEM_WIDTH, BLACK_FILL);
mouse_newmenu( &rmenu, regmenu_names, reg_items, reg_names,
NUM_REG_ITEMS, ITEM_WIDTH, BLACK_FILL);
mouse_newmenu( &cmenu, commenu_names, com_items, com_names,
NUM_COM_ITEMS, ITEM_WIDTH, BLACK_FILL);
mouse_newmenu( &omenu, optmenu_names, opt_items, opt_names,
NUM_OPT_ITEMS, ITEM_WIDTH, BLACK_FILL);
pmenu.NextMenu = &rmenu;
rmenu.NextMenu = &cmenu;
cmenu.NextMenu = &omenu;
reg_items[0].Command = 'X';
reg_items[1].Command = 'C';
reg_items[2].Command = 'P';
reg_items[0].Flags |= COMMSEQ;
reg_items[1].Flags |= COMMSEQ;
reg_items[2].Flags |= COMMSEQ;
SetMenuStrip(Window, &pmenu); /* Set up the menu here */
}
mouse_clear_menu()
{
ClearMenuStrip(Window, &cmenu);
}
static
do_menu( m, f, n) /* execute a menu command */
{
int menu, item, sub;
menu = MENUNUM( m);
item = ITEMNUM( m);
sub = SUBNUM( m);
if( kbdmip != NULL) /* collecting macro */
{
if ( menu == COM_MENU && item == ENDM_ITEM ) /* End macro */
;
else
{
ctrlg(FALSE, 0);
return( FALSE );
}
}
switch( menu)
{
case PRO_MENU:
switch( item)
{
case NEWBUF_ITEM:
usebuffer( f, n);
break;
case OPEN_ITEM:
fileread( f, n);
break;
case SAVE_ITEM:
filesave( f, n);
break;
case SAVEAS_ITEM:
filewrite( f, n);
break;
case QUITNSAVE_ITEM:
quickexit( f, n);
break;
case QUIT_ITEM:
quit( f, n);
break;
}
break;
case REG_MENU:
switch( item)
{
case COPY_ITEM:
copyregion( f, n);
break;
case KILL_ITEM:
killregion( f, n);
break;
case UNKILL_ITEM:
yank( f, n);
break;
case FILEYANK_ITEM:
fileyank( f, n);
break;
}
break;
case COM_MENU:
switch( item)
{
case NOOP_ITEM:
break;
case SEARCH_ITEM:
forwsearch( f, n);
break;
case QUERY_ITEM:
qreplace( f, n);
break;
case STARTM_ITEM:
ctlxlp( f, n);
break;
case ENDM_ITEM:
ctlxrp( f, n);
break;
case EXECM_ITEM:
ctlxe( f, n);
break;
case NEW_ITEM:
spawncli( f, n);
break;
}
break;
case OPT_MENU:
switch( item )
{
case TWO_ITEM:
splitwind( f, n);
break;
case ONE_ITEM:
onlywind( f, n);
break;
case WORDRAP_ITEM:
togglewordwrap( f, n);
break;
case AUTOIND_ITEM:
toggleautoindent( f, n);
break;
case LEFTMAR_ITEM:
setfillcol( 0, n);
break;
case RIGHTMAR_ITEM:
setfillcol( 1, n);
break;
}
break;
default:
break;
}
}
mouse_handle_event( f, n)
{
register char *s;
int result, c, class, subclass, keycode, qualifiers, x, y, secs, musecs;
char instr[ 88 ]; /* 8 nine digit numbers with separators + 1 */
static int netx, nety;
static int button_now = 0, button_ever = 0;
for ( s = instr; (*s++ = ttgetc()) != '|';)
;
*s = 0; /* terminate the str */
sscanf( instr, "%d;%d;%d;%d;%d;%d;%d;%d|",
&class, &subclass, &keycode, &qualifiers, &x, &y, &secs, &musecs);
switch( class)
{
case 2: /* mouse button--only get this for left button */
if( keycode & 0x80) /* key up */
{
keycode &= ~0x80; /* clear the up bit */
button_now &= ~ LEFT_BUTTON;
}
else /* key down */
{
netx = Window->MouseX - Window->BorderLeft; /* save coords */
nety = Window->MouseY - Window->BorderTop;
button_now |= LEFT_BUTTON;
button_ever |= LEFT_BUTTON;
}
break;
case 10: /* menu selection -- right button up only */
if( keycode == MENUNULL)
{
netx = Window->MouseX - Window->BorderLeft; /* save coords */
nety = Window->MouseY - Window->BorderTop;
button_ever |= RIGHT_BUTTON;
}
else /* made a menu selection */
{
button_ever = 0; /* ignore other buttons */
do_menu( keycode, f, n);
}
break;
}
if ( (!button_now) && button_ever ) /* buttons were pushed: interpret */
{
switch( button_ever)
{
case LEFT_BUTTON:
mouse_to_xy( netx, nety);
break;
case RIGHT_BUTTON:
mouse_set_mark( netx, nety);
break;
case LEFT_BUTTON | RIGHT_BUTTON:
forwdel( f, n);
break;
}
button_ever = 0;
}
}
mouse_newmenu( menu, item_names, menu_items, menu_text, num_items,
Mwidth, flag)
struct Menu *menu; /* Menu structure */
char *item_names[]; /* Pointer to array of item names */
struct MenuItem menu_items[]; /* pointer to array of structures */
struct IntuiText menu_text[]; /* Pointer to array of text structures */
int num_items; /* Number of items */
int Mwidth; /* Menu Width */
int flag; /* Special Item flag for ALL items */
{
int i;
int height = 0;
for (i=0; i< num_items; i++) {
menu_text[i] = generic; /* stamp generic template */
menu_text[i].IText = (UBYTE *) item_names[i]; /* mv string ptrs */
menu_items[i].NextItem = &menu_items[i+1]; /* Lnk to nxt item */
menu_items[i].TopEdge = 10 * i; /* Top rect of item */
menu_items[i].LeftEdge = 0;
menu_items[i].Height = 8;
menu_items[i].ItemFill = (APTR)&menu_text[i];
menu_items[i].Flags = flag;
menu_items[i].Width = Mwidth;
menu_items[i].MutualExclude = 0x0000;
menu_items[i].Command = 0;
menu_items[i].SubItem = NL;
menu_items[i].NextSelect = NL;
height += 10;
}
menu_items[num_items-1].NextItem = NULL;
menu->Height = height;
}
static
winddist( w, row, col) /* calc distance of window from this row, col */
WINDOW *w;
{
int d;
if( row < w->w_toprow) /* above window */
return( w->w_toprow - row);
else if( row < (w->w_toprow + w->w_ntrows)) /* within window */
return( 0);
else /* below window */
return( row - (w->w_toprow + w->w_ntrows));
}
WINDOW *
mouse_find_wind( row, col) /* find window containing this row, col */
{
WINDOW *w, *result_w;
int distance, result_distance;
result_distance = HUGE; /* greater than any real distance */
for( w = wheadp; w != NULL; w = w->w_wndp) {
distance = winddist( w, row, col);
if( distance < result_distance) {
result_w = w;
result_distance = distance;
}
}
return( result_w);
}
static
get_wintop( this_w) /* return row for top of this window */
WINDOW *this_w;
{
register WINDOW *w;
register int row;
row = 0;
for( w = wheadp; w != this_w; w = w->w_wndp) {
row += w->w_ntrows +1;
}
return( row);
}
mouse_to_xy( x, y) /* move point to position at coords x,y */
{
register LINE *dlp;
register int row, col;
WINDOW *w;
row = y / FONT_Y; /* convert coords to row and col */
col = x / FONT_X;
w = mouse_find_wind( row, col); /* find the window and make it current */
curwp = w;
curbp = curwp->w_bufp;
row -= get_wintop( curwp); /* adjust to row in window */
if( row >= curwp->w_ntrows) row = curwp->w_ntrows -1;
dlp = curwp->w_linep;
while (row-- && dlp!=curbp->b_linep) {
dlp = lforw(dlp);
}
curwp->w_dotp = dlp;
curgoal = col; /* aim for this col */
curwp->w_doto = getgoal(dlp);
}
mouse_set_mark( x, y) /* set mark at mouse cursor */
{
WINDOW *wp;
LINE *dlp;
int offset;
/* save current position */
wp = curwp;
dlp = curwp->w_dotp;
offset = curwp->w_doto;
/* go to cursor position, set mark, and announce */
mouse_to_xy( x, y);
update();
setmark( FALSE, 1);
update();
/* return to former position */
curwp = wp;
curbp = curwp->w_bufp;
curwp->w_dotp = dlp;
curwp->w_doto = offset;
}
mouse_enable() /* this must be last to keep ctags happy */
{
ttputs( "\x1b[2;10{"); /* get mouse button and menu events */
ttflush();
}